package com.htfyun.ft.rooboUtils;

import android.content.Context;
import android.os.Bundle;
import android.util.Log;

import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechUtility;
import com.iflytek.cloud.VoiceWakeuper;
import com.iflytek.cloud.WakeuperListener;
import com.iflytek.cloud.WakeuperResult;
import com.iflytek.cloud.util.ResourceUtil;

import org.json.JSONException;
import org.json.JSONObject;

/**
 * Created by yuanshuqi on 2016/10/13 17:06.
 * email:yuanshuqi@roo.bo
 */

public class XunFeiWakeUpTranslator {
    private static final String TAG = "XunFeiWakeUpTranslator";
    private final static int MIN = -20;
    private final Object lock = new Object();
    private final Context mContext;
    private volatile VoiceWakeuper mIvw;
    private String mWakeupRes;
    private int count;
    private boolean mHasInit;
    private int mScore = 0;
    private WakeupListener mListener;

    /**
     * 路径格式：ResourceUtil.generateResourcePath(context, ResourceUtil.RESOURCE_TYPE.assets, "ivw/552cd878.jet");
     * ivw是assets下的文件夹，.jet文件是唤醒的资源文件
     *
     * @param wakeupRes
     */
    public XunFeiWakeUpTranslator(String wakeupRes, Context context) {
        mWakeupRes = wakeupRes;
        this.mContext = context;
    }

    public void init() {
        if (mHasInit) {
            return;
        }
        mHasInit = true;

        initIFlyTekWakeup();
    }

    private boolean initIFlyTekWakeup() {
        synchronized (lock) {
            createWakeUper();
            if (mIvw == null) {
                return false;
            }
            setWakeUpParams();
        }
        Log.e(TAG, "初始化wakeup成功");
        return true;
    }

    private void setWakeUpParams() {
        // 清空参数
        mIvw.setParameter(SpeechConstant.PARAMS, null);
        // 唤醒门限值，根据资源携带的唤醒词个数按照“id:门限;id:门限”的格式传入
        mIvw.setParameter(SpeechConstant.IVW_THRESHOLD, "0:" + MIN + ";1:" + MIN + ";2:"
                + MIN + ";3:" + MIN);
        // 设置唤醒模式
        mIvw.setParameter(SpeechConstant.IVW_SST, "wakeup");
        // 设置持续进行唤醒
        mIvw.setParameter(SpeechConstant.KEEP_ALIVE, "1");
        // mIvw.SpeechConstant.IVW_WORD_PATH/
        mIvw.setParameter(SpeechConstant.AUDIO_SOURCE, "-1");
        mIvw.setParameter(SpeechConstant.SAMPLE_RATE, "16000");
        mIvw.setParameter(SpeechConstant.IVW_RES_PATH, mWakeupRes);
        mIvw.setParameter(SpeechConstant.IVW_NET_MODE, "0");
        mIvw.startListening(mWakeupListener);
        Log.d(TAG, "initWakeuperLocked finished");
    }

    private void createWakeUper() {
        if (mIvw != null) {
            if (mIvw.isListening()) {
                mIvw.stopListening();
            }
            Log.d(TAG, "destroy old wakeuper");
            mIvw.destroy();
            mIvw = null;
        }
        VoiceWakeuper.getWakeuper();
        StringBuffer param = new StringBuffer();
        param.append(SpeechConstant.IVW_RES_PATH + "=" + mWakeupRes).append("," + ResourceUtil.ENGINE_START + "=" + SpeechConstant.ENG_IVW);
        SpeechUtility.getUtility().setParameter(ResourceUtil.ENGINE_START, param.toString());
        mIvw = VoiceWakeuper.createWakeuper(mContext, null);
        Log.d(TAG, "create VoiceWakeuper success...");
    }

    public void translateVoice(byte[] pcm) {
        writePcmToEngine(pcm);
    }

    protected void writePcmToEngine(byte[] voiceData) {
        mIvw.writeAudio(voiceData, 0, voiceData.length);
    }

    public void setScore(int score) {
        this.mScore = score;
    }

    private WakeuperListener mWakeupListener = new WakeuperListener() {

        @Override
        public void onResult(WakeuperResult result) {
            Log.d(TAG, "WeakUpThread onResult called ");
            // WakeUpListenerResult();
            String resultString;
            try {
                String text = result.getResultString();
                Log.e(TAG, "--->> onResult result.getResultString()=" + result.getResultString());
                JSONObject object = new JSONObject(text);
                StringBuffer buffer = new StringBuffer();
                buffer.append("【RAW】 ").append(text).append("\n").append("【操作类型】").append(object.optString("sst")).append("\n")
                        .append("【唤醒词id】").append(object.optString("id")).append("\n").append("【得分】").append(object.optString("score"))
                        .append("\n").append("【前端点】").append(object.optString("bos")).append("\n").append("【尾端点】").append(object.optString("eos"));
                resultString = buffer.toString();
                int score = object.optInt("score");
                if (score >= mScore) {
                    Log.e(TAG, "===================== wake up ================");
                    if (mListener != null) {
                        mListener.onWakeUp(object.toString());
                    }
                }
            } catch (JSONException e) {
                resultString = "结果解析出错";
                e.printStackTrace();
            }
            Log.e(TAG, resultString);
        }

        @Override
        public void onError(SpeechError error) {
            Log.e(TAG, "唤醒服务error" + error.getErrorCode() + ", " + error.getErrorDescription());
        }

        @Override
        public void onBeginOfSpeech() {
            Log.e(TAG, "唤醒服务打开，可以说话");
        }

        @Override
        public void onEvent(int eventType, int isLast, int arg2, Bundle obj) {
            Log.e(TAG, "唤醒服务onEvent");
        }

        @Override
        public void onVolumeChanged(int arg0) {
        }
    };

    public void setWakeupListener(WakeupListener listener) {
        this.mListener = listener;
    }

    public int getScore() {
        return mScore;
    }

    public void destory() {
        if (mIvw != null) {
            if (mIvw.isListening()) {
                mIvw.stopListening();
            }
            Log.d(TAG, "destroy old wakeuper");
            mIvw.destroy();
            mIvw = null;
        }
    }

    public interface WakeupListener {
        void onWakeUp(String json);
    }
}
